﻿using DataStructure;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.IO;

namespace DataStructure.Test
{
    
    
    /// <summary>
    ///This is a test class for PermutationTest and is intended
    ///to contain all PermutationTest Unit Tests
    ///</summary>
    [TestClass()]
    public class PermutationTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


        /// <summary>
        ///A test for Permutation Constructor
        ///</summary>
        [TestMethod()]
        public void PermutationConstructorTest()
        {
            Permutation p4 = new Permutation(4, 5);
            Console.WriteLine("\nThe 5th permutation of order 4 is:");
            Console.WriteLine(p4.ToString());
            p4 = new Permutation(10, 999999);
            Console.WriteLine("\nThe 999,999th permutation of order 10 is:");
            Console.WriteLine(p4.ToString());
        }

        /// <summary>
        ///A test for Successor
        ///</summary>
        [TestMethod()]
        public void SuccessorTest()
        {
            Permutation p5 = new Permutation(new int[] { 2, 1, 3, 5, 4, 0 });
            Console.WriteLine("\nThe successor to ( 2 1 3 5 4 0 ) is");
            Console.WriteLine(p5.Successor().ToString());

            p5 = new Permutation(3);
            Console.WriteLine("\nAll permutations of order 3 are:");
            Console.WriteLine(p5.ToString());
            while ((p5 = p5.Successor()) != null)
                Console.WriteLine(p5.ToString());

        }


        /// <summary>
        ///A test for ApplyTo
        ///</summary>
        [TestMethod()]
        public void ApplyToTest()
        {
            Permutation p6 = new Permutation(8, 1395);
            Console.WriteLine("\nThe permutation is:");
            Console.WriteLine(p6.ToString());

            object[] bits = new object[] { "1", "0", "1", "0", "1", "0", "1", "0" };

            Console.WriteLine("\nBits before permutation:");
            for (int i = 0; i < 8; ++i)
            {
                Console.Write(bits[i].ToString());
            }
            Console.WriteLine("");

            bits = p6.ApplyTo(bits);

            Console.WriteLine("\nBits after permutation:");
            for (int i = 0; i < 8; ++i)
            {
                Console.Write(bits[i].ToString());
            }
            Console.WriteLine("");

            bits = p6.Inverse().ApplyTo(bits);

            Console.WriteLine("\nBits after inverting the permutation:");
            for (int i = 0; i < 8; ++i)
            {
                Console.Write(bits[i].ToString());
            }
            Console.WriteLine("");
        }

        /// <summary>
        ///A test for Inverse
        ///</summary>
        [TestMethod()]
        public void InverseTest()
        {
            Console.WriteLine("\nCreating file testcases.txt");
            FileStream fs = new FileStream("testcases.txt", FileMode.Create);
            StreamWriter sw = new StreamWriter(fs);
            int id = 1;

            object[] colors = new object[] { "aqua", "blue", "cyan", "darkgreen" };
            object[] casedata = new object[colors.Length];

            Permutation p7 = new Permutation(colors.Length);

            while (p7 != null)
            {
                sw.Write(id++.ToString().PadLeft(6, '0') + ":");
                casedata = p7.ApplyTo(colors);
                sw.Write(casedata[0].ToString() + ":" + casedata[1].ToString() + ":");
                sw.Write(casedata[2].ToString() + ":" + casedata[3].ToString() + ":");

                if (casedata[3].ToString() == "blue")
                    sw.WriteLine("darkgreen");
                else if (casedata[0].ToString().CompareTo(casedata[2].ToString()) < 0)
                    sw.WriteLine(casedata[0].ToString());
                else
                    sw.WriteLine(casedata[2].ToString());

                p7 = p7.Successor();
            }

            sw.Flush();
            sw.Close();
            fs.Close();
        }
    }
}
